package com.neuronbit.businessflow.intellij.editor.swing.editor.propertyInspector.properties;

import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.Computable;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiParameter;
import com.neuronbit.businessflow.intellij.editor.UIDesignerBundle;
import com.neuronbit.businessflow.intellij.editor.swing.editor.FormEditingUtil;
import com.neuronbit.businessflow.intellij.editor.swing.editor.RadJavaMethodComponent;
import com.neuronbit.businessflow.intellij.editor.swing.editor.propertyInspector.Property;
import com.neuronbit.businessflow.intellij.editor.swing.editor.propertyInspector.PropertyEditor;
import com.neuronbit.businessflow.intellij.editor.swing.editor.propertyInspector.PropertyRenderer;
import com.neuronbit.businessflow.intellij.editor.swing.editor.propertyInspector.renderers.LabelPropertyRenderer;
import com.neuronbit.businessflow.intellij.model.FormattedMethodString;
import com.neuronbit.businessflow.intellij.util.PsiUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * The type Method params property.
 */
public class CallableMethodParamsProperty extends Property<RadJavaMethodComponent, String> {

    private final PropertyEditor myEditor;

    /**
     * Instantiates a new Method params property.
     *
     * @param component the component
     * @param name      the name
     */
    public CallableMethodParamsProperty(RadJavaMethodComponent component, String name) {
        super(null, name);
        myEditor = new ChangeMethodSignaturePropertyEditor(component);
    }

    @Override
    public String getValue(RadJavaMethodComponent component) {
        return "";
    }

    @Override
    protected void setValueImpl(RadJavaMethodComponent component, String value) throws Exception {

    }

    @Override
    public @NotNull PropertyRenderer getRenderer() {
        return new LabelPropertyRenderer(UIDesignerBundle.message("client.properties.configure"));
    }

    @Override
    public @Nullable PropertyEditor<String> getEditor() {
        return myEditor;
    }

    @Override
    public Property @NotNull [] getChildren(RadJavaMethodComponent component) {
        return ApplicationManager.getApplication().runReadAction((Computable<Property[]>) () -> {
            if (component.getClassToBind() == null) {
                return EMPTY_ARRAY;
            }
            PsiClass clazz = FormEditingUtil.findClassToBind(component.getModule(), component.getClassToBind());
            if (clazz == null) {
                return EMPTY_ARRAY;
            }
            FormattedMethodString methodToBind = component.getMethodToBind();
            if (methodToBind != null) {
                String methodName = methodToBind.getName();
                PsiMethod[] psiMethods = clazz.findMethodsByName(methodName, true);
                if (ArrayUtils.isNotEmpty(psiMethods)) {
                    for (PsiMethod psiMethod : psiMethods) {
                        if (PsiUtils.formatMethod(psiMethod).equals(methodToBind.getValue())) {
                            PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
                            Property[] properties = new Property[parameters.length];
                            for (int i = 0; i < parameters.length; i++) {
                                properties[i] = new CallableMethodParamProperty(this, component.getProject(), parameters[i], i + "");
                            }
                            return properties;
                        }
                    }
                }
            }

            return EMPTY_ARRAY;
        });

    }
//
//    @Override
//    public boolean needRefreshPropertyList() {
//        return true;
//    }


}
